/**
 * @file bsp_exit.c
 * @author 何传喜
 * @brief 外部中断驱动
 * @version 0.1
 * @date 2023-09-12
 * @note 2023-09-12 配置按键对应的 GPIO 为中断模式
 * 
 * @copyright Copyright (c) 2023
 * 
 */
#include "bsp_exit.h"
#include "bsp_gpio.h"
#include "bsp_int.h"
#include "bsp_delay.h"
#include "bsp_led.h"

/**
 * @brief 初始化外部中断
 * @param 无
 * @return 无
 */
void exit_init(void)
{
    gpio_pin_config_t key_config;
    
    /* 1、设置 IO 复用 */
    IOMUXC_SetPinMux(IOMUXC_UART1_CTS_B_GPIO1_IO18, 0);
    IOMUXC_SetPinConfig(IOMUXC_UART1_CTS_B_GPIO1_IO18, 0xF080);
    /* 2、初始化 GPIO 为中断模式 */
    key_config.direction = kGPIO_DigitalInput;
    key_config.interruptMode = kGPIO_IntFallingEdge;
    key_config.outputLogic = 1;
    gpio_init(GPIO1, 18, &key_config);
    /* 3、使能 GIC 中断、注册中断服务函数、使能 GPIO 中断 */
    GIC_EnableIRQ(GPIO1_Combined_16_31_IRQn);
    system_register_irqhandler(GPIO1_Combined_16_31_IRQn,
                               (system_irq_handler_t)gpio1_io18_irqhandler,
                               NULL);
    gpio_enableint(GPIO1, 18);
}

/**
 * @brief GPIO1_IO18 最终的中断处理函数
 * @param 无
 * @return 无
 */
void gpio1_io18_irqhandler(void)
{
    static unsigned char state = 0;
    /* 采用延时消抖，中断服务函数中禁止使用延时函数，因为中断服务函数需要快进快出，
     * 这里是为了演示所以使用延时消抖，后续采用定时器中断消抖 
     */
    delay(10);
    if (gpio_pinread(GPIO1, 18) == 0) { /* 按键按下了 */
        state = !state;
        led_switch(LED0, state);
    }
    gpio_clearintflags(GPIO1, 18); /* 清除中断标志 */
}
